import React, { useState, useRef, useEffect } from 'react';
import PropTypes from 'prop-types';

/**
 * 虚拟滚动列表组件
 * @param {Array} data - 列表数据
 * @param {Function} renderItem - 渲染函数
 * @param {number} itemHeight - 每项高度(px)
 * @param {number} visibleCount - 可见区域能显示的条目数
 * @param {number} bufferCount - 缓冲区条目数
 */
const VirtualScrollList = ({ 
  data, 
  renderItem, 
  itemHeight = 50, 
  visibleCount = 10, 
  bufferCount = 5 
}) => {
  const containerRef = useRef(null);
  const [startIndex, setStartIndex] = useState(0);
  const totalHeight = data.length * itemHeight;
  const endIndex = Math.min(startIndex + visibleCount + bufferCount, data.length);

  useEffect(() => {
    const container = containerRef.current;
    if (!container) return;

    const handleScroll = () => {
      const scrollTop = container.scrollTop;
      const newStartIndex = Math.max(
        0, 
        Math.floor(scrollTop / itemHeight) - bufferCount
      );
      setStartIndex(newStartIndex);
    };

    container.addEventListener('scroll', handleScroll);
    return () => container.removeEventListener('scroll', handleScroll);
  }, [itemHeight, bufferCount]);

  const visibleItems = data.slice(startIndex, endIndex);
  const offsetY = startIndex * itemHeight;

  return (
    <div 
      ref={containerRef}
      style={{
        height: `${visibleCount * itemHeight}px`, 
        overflow: 'auto',
        position: 'relative',
      }}
    >
      <div style={{ height: `${totalHeight}px` }}>
        <div style={{ transform: `translateY(${offsetY}px)` }}>
          {visibleItems.map((item, index) => (
            <div key={startIndex + index} style={{ height: `${itemHeight}px` }}>
              {renderItem(item, startIndex + index)}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
};

VirtualScrollList.propTypes = {
  data: PropTypes.array.isRequired,
  renderItem: PropTypes.func.isRequired,
  itemHeight: PropTypes.number,
  visibleCount: PropTypes.number,
  bufferCount: PropTypes.number,
};

export default VirtualScrollList;
